package com.ld.admin.service.codegen;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Service;

import com.ld.admin.model.system.codegen.CodegenDbsetModel;
import com.ld.common.service.ProjectBasicService;
import com.ld.shieldsb.codegen.model.export.ExportParams;
import com.ld.shieldsb.codegen.model.export.ExportParamsModelFieldsModel;
import com.ld.shieldsb.codegen.model.export.ExportResult;
import com.ld.shieldsb.codegen.service.CodeGenService;
import com.ld.shieldsb.common.core.model.PropertiesModel;
import com.ld.shieldsb.common.core.model.Result;
import com.ld.shieldsb.common.core.reflect.ClassUtil;
import com.ld.shieldsb.common.core.util.ResultUtil;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.web.BasicService;
import com.ld.shieldsb.common.web.util.Web;
import com.ld.shieldsb.db.model.DBSetInfo;
import com.ld.shieldsb.db.model.DBTableColumnModel;
import com.ld.shieldsb.db.model.DBTableModel;
import com.ld.shieldsb.db.service.DBTabelService;

@Service
public class CodegenService extends ProjectBasicService {

    /**
     * 获取默认数据库配置信息
     * 
     * @Title getDefaultDbSetInfo
     * @author 吕凯
     * @date 2018年12月19日 上午11:38:40
     * @param dbConnId
     * @return DBSetInfo
     */
    public DBSetInfo getDbSetInfo(Long dbConnId) {
        DBSetInfo dbSetInfo = new DBSetInfo();
        if (dbConnId == 0) {
            dbSetInfo.setDbUrl(PropertiesModel.CONFIG.getString("db0.url"));
            dbSetInfo.setDbUserName(PropertiesModel.CONFIG.getString("db0.username"));
            dbSetInfo.setDbPassword(PropertiesModel.CONFIG.getString("db0.password"));
        } else {
            CodegenDbsetModel dbSet = getOne(CodegenDbsetModel.class, dbConnId);
            if (dbSet != null) {
                dbSetInfo.setDbUrl(dbSet.getDbUrl());
                dbSetInfo.setDbUserName(dbSet.getDbUserName());
                dbSetInfo.setDbPassword(dbSet.getDbPassword());
            }
        }
        return dbSetInfo;
    }

    /**
     * 获取dbset对象
     * 
     * @Title getDbSetInfo
     * @author 吕凯
     * @date 2019年11月27日 上午8:41:08
     * @param url
     * @param userName
     * @param password
     * @return DBSetInfo
     */
    public DBSetInfo getDbSetInfo(String url, String userName, String password) {
        DBSetInfo dbSetInfo = new DBSetInfo();
        dbSetInfo.setDbUrl(url);
        dbSetInfo.setDbUserName(userName);
        dbSetInfo.setDbPassword(password);
        return dbSetInfo;
    }

    public Result getCreateTableSql() {
        Result result = getDBConn();
        if (!result.getSuccess()) {
            return Web.Response.result(result);
        }
        DBSetInfo dbSetInfo = (DBSetInfo) result.getData();
        String tableName = getString("tableName");
        String tableComments = getString("tableComments");
        DBTableModel dbTableModel = new DBTableModel();
        dbTableModel.setTableName(tableName);
        dbTableModel.setTableComments(tableComments);
        List<DBTableColumnModel> columns = new ArrayList<>();
        List<String> columnNameList = getList("columnName");
        List<String> dataTypeList = getList("dataType"); // 字段类型
        List<String> datasizeList = getList("datasize");
        List<String> defaultList = getList("default"); // 字段显示名称（注释及列表页）
        List<String> ispkList = getList("ispk"); // 主键
        List<String> notNullableList = getList("notnullable"); // input类型
        List<String> remarksList = getList("remarks"); // input类型
        for (int i = 0; i < columnNameList.size(); i++) {
            String columnName = columnNameList.get(i);
            String dataType = dataTypeList.get(i);
            String datasize = datasizeList.get(i);
            if (StringUtils.isNotBlank(datasize)) {
                dataType += "(" + datasize + ")";
            }
            int notNullable = ClassUtil.obj2int(notNullableList.get(i));
            String defaultVal = defaultList.get(i);
            String remarks = remarksList.get(i);
            int ispk = ClassUtil.obj2int(ispkList.get(i));
            DBTableColumnModel columnModel = new DBTableColumnModel();
            columnModel.setColumnName(columnName);
            columnModel.setDataType(dataType);
            columnModel.setNullable(notNullable == 0);
            columnModel.setDefaultValue(defaultVal);
            columnModel.setRemarks(remarks);
            columnModel.setIsPrimaryKey(ispk == 1);
            columns.add(columnModel);
        }
        dbTableModel.setColumns(columns);
        DBTabelService service = DBTabelService.getInstance(dbSetInfo);

        String createTableStr = service.getCreateTableSql(dbTableModel);
        return ResultUtil.success("", createTableStr);
    }

    public Result getDBConn() {
        Long dbConnId = getLong("conn");
        DBSetInfo dbSetInfo = getDbSetInfo(dbConnId);
        // 验证是否可以连接
        Result result = testCon(dbSetInfo);
        if (!result.getSuccess()) {
            return Web.Response.result(result);
        }
        return Web.Response.success("", dbSetInfo);
    }

    public Result testCon(DBSetInfo dbSetInfo) {
        // 验证是否可以连接
        Result result = DBTabelService.testCon(dbSetInfo.getDbUrl(), dbSetInfo.getDbUserName(), dbSetInfo.getDbPassword());
        if (!result.getSuccess()) {
            return Web.Response.error("数据库连接出错：" + dbSetInfo.getDbUrl() + "！" + result.getMessage());
        }
        return Web.Response.success("");
    }

    /**
     * 建表
     * 
     * @Title createTable
     * @author 吕凯
     * @date 2019年4月26日 下午2:02:46
     * @return
     * @throws Exception
     *             Result
     */
    public Result createTable() {
        Result result = getCreateTableSql();
        if (!result.getSuccess()) {
            return Web.Response.error("建表失败！" + result.getMessage());
        } else {
            String sql = (String) result.getData();
            Long dbConnId = getLong("conn");
            DBSetInfo dbSetInfo = getDbSetInfo(dbConnId);
            DBTabelService service = DBTabelService.getInstance(dbSetInfo);
            result = service.createTable(sql);
            if (!result.getSuccess()) {
                return Web.Response.error("建表失败！" + result.getMessage());
            }
        }
        return Web.Response.success("建表完成，请到数据库中检查是否正确！");
    }

    /**
     * 获取生成的代码
     * 
     * @Title getCreateCodeStr
     * @author 吕凯
     * @date 2019年4月26日 下午2:21:07
     * @param model
     * @param outtypes
     * @return ExportResult
     */
    public ExportResult getCreateCodeStr(ExportParams model, List<String> outtypes) {
        String tableName = getString("tableName");
        List<ExportParamsModelFieldsModel> columnsList = new ArrayList<>();
        List<String> columnNameList = getList("columnName");
        List<String> fieldNameList = getList("fieldName"); // 字段显示名称（注释及列表页）
        List<String> fieldTypeList = getList("fieldType");
        List<String> remarksList = getList("showName"); // 字段显示名称（注释及列表页）
        List<String> searchTypeList = getList("searchType"); // 搜索类型
        List<String> inputTypeList = getList("inputType"); // input类型
        for (int i = 0; i < columnNameList.size(); i++) {
            String columnName = columnNameList.get(i);
            String fieldName = fieldNameList.get(i);
            ExportParamsModelFieldsModel fieldModel = new ExportParamsModelFieldsModel();
            if (CodeGenService.UN_UPDATED_FIELD.contains(columnName.toLowerCase())) {
                fieldModel.setIsShowInUpdate(false); // 更新页面不显示
            }
            fieldModel.setTableName(tableName);
            fieldModel.setColumnName(columnName);
            fieldModel.setFieldName(fieldName);
            fieldModel.setFieldType(fieldTypeList.get(i));
            fieldModel.setComments(remarksList.get(i));
            fieldModel.setCanSearch(getInt("cansearch-" + columnName) == 1); // 搜索页是否作为搜索条件
            if (fieldModel.getCanSearch()) { //
                fieldModel.setSearchType(searchTypeList.get(i)); // 搜索类型
            }
            fieldModel.setIsShowInList(getInt("listshow-" + columnName) == 1); // 列表页是否显示
            fieldModel.setFormvalidateMethods(getList("formvalidate-" + columnName)); // 获取表单验证设置
            fieldModel.setInputType(inputTypeList.get(i));
            columnsList.add(fieldModel);
        }
        model.setColumns(columnsList);
        ExportResult result;
        result = CodeGenService.createCode(outtypes, model);
        return result;
    }

    public static void main(String[] args) {
        BasicService basicService = new BasicService();
        System.out.println(basicService.getBaseDAO());
        CodegenService service = new CodegenService();
        System.out.println(service.getBaseDAO());
        System.out.println(basicService.getBaseDAO());
    }

}
